home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / port / seq / dynloader.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  4.6 KB  |  227 lines

  1. /*
  2.  
  3. !!!! Be sure that we close all open files up exit on the Sequent - the ld !!!!
  4.      fails otherwise 
  5.  
  6.      $Header: /private/postgres/src/port/seq/RCS/dynloader.c,v 1.18 1992/01/12 23:28:30 mao Exp $
  7. */
  8.  
  9. #include <pwd.h>
  10. #include <stdio.h>
  11. #include <sys/types.h>
  12. #include <sys/param.h>
  13. #include <sys/stat.h>
  14. #include <sys/file.h>
  15.  
  16. extern char pg_pathname[];
  17.  
  18. #include <a.out.h>
  19.  
  20. #include "tmp/c.h"
  21. #include "utils/fmgr.h"
  22.  
  23. /*
  24.  * Allow extra space for "overruns" caused by the link.
  25.  */
  26.  
  27. #define FUDGE 10000
  28.  
  29. static char *temp_file_name = NULL;
  30. static char *path = "/usr/tmp/postgres";
  31.  
  32. DynamicFunctionList *
  33. dynamic_file_load(err, filename, address, size)
  34.  
  35. char **err, *filename, **address;
  36. long *size;
  37.  
  38. {
  39.     extern char *valloc();
  40.  
  41.     int nread;
  42.     struct exec ld_header, header;
  43.     unsigned long image_size, true_image_size;
  44.     char *load_address = NULL;
  45.     FILE *temp_file = NULL;
  46.     DynamicFunctionList *retval = NULL, *load_symbols();
  47.     int fd;
  48.     char foo[10];
  49.  
  50.     closeAllVfds(); /* We run out of open files in running on the Sequent */
  51.  
  52.     fd = open(filename, O_RDONLY);
  53.  
  54.  
  55.     if (fd == -1)
  56.     {
  57.         *err = "error opening file";
  58.         goto finish_up;
  59.     }
  60.  
  61.     read(fd, &ld_header, sizeof(struct exec));
  62.  
  63.     image_size = ld_header.a_text + ld_header.a_data + ld_header.a_bss + FUDGE;
  64.  
  65.     close(fd); /* don't open it until the load is finished. */
  66.  
  67.     if (!(load_address = valloc(image_size)))
  68.     {
  69.         *err = "unable to allocate memory";
  70.         goto finish_up;
  71.     }
  72.  
  73.     if (temp_file_name == NULL)
  74.     {
  75.         sprintf(foo, "%d", getpid());
  76.         temp_file_name = (char *)malloc(strlen(path) + strlen(foo) + 2);
  77.         strcpy(temp_file_name, path);
  78.         strcat(temp_file_name, foo);
  79.     }
  80.  
  81.     if(execld(load_address, temp_file_name, filename))
  82.     {
  83.         *err = "link failed!";
  84.         goto finish_up;
  85.     }
  86.  
  87.     if(!(temp_file = fopen(temp_file_name,"r")))
  88.     {
  89.         *err = "unable to open tmp file";
  90.         goto finish_up;
  91.     }
  92.     nread = fread(&header, sizeof(header), 1, temp_file);
  93.     true_image_size = header.a_text + header.a_data + header.a_bss;
  94.  
  95.     if (true_image_size > image_size)
  96.     {
  97.         fclose(temp_file);
  98.         free(load_address);
  99.         load_address = valloc(true_image_size);
  100.  
  101.         if (execld(load_address, temp_file_name, filename))
  102.         {
  103.             *err = "ld failed!";
  104.             goto finish_up;
  105.         }
  106.         temp_file = fopen(temp_file_name,"r");
  107.         nread = fread(&header, sizeof(header), 1, temp_file);
  108.     }
  109.  
  110.     fseek(temp_file, N_TXTOFF(header), 0);
  111.     nread = fread(load_address, true_image_size,1,temp_file);
  112.  
  113.     retval = load_symbols(filename, &ld_header, load_address);
  114.  
  115.     fclose(temp_file);
  116.     unlink(temp_file_name);
  117.     *address = load_address;
  118.     *size = image_size;
  119.  
  120.     temp_file = NULL;
  121.     load_address = NULL;
  122.  
  123. finish_up:
  124.     if (temp_file != NULL) fclose(temp_file);
  125.     if (load_address != NULL) free(load_address);
  126.     return retval;
  127. }
  128.  
  129. DynamicFunctionList *
  130. load_symbols(filename, hdr, entry_addr)
  131.  
  132. char *filename;
  133. struct exec *hdr;
  134. int entry_addr;
  135.  
  136. {
  137.     int fd;
  138.     char *strings, *symb_table, *p, *q;
  139.     int symtab_offset, string_offset, string_size, nsyms, i;
  140.     struct nlist *table_entry;
  141.     int entering = 1;
  142.     DynamicFunctionList *head, *scanner;
  143.  
  144.     symtab_offset = N_SYMOFF(*hdr);
  145.     string_offset = N_STROFF(*hdr);
  146.  
  147.     fd = open(filename, O_RDONLY);
  148.  
  149.     lseek(fd, string_offset, 0);
  150.     read(fd, &string_size, sizeof(string_size));
  151.     strings = (char *) malloc(string_size - 4);
  152.     read(fd, strings, string_size - 4);
  153.     nsyms = hdr->a_syms / sizeof(struct nlist);
  154.     lseek(fd, symtab_offset, 0);
  155.     symb_table = (char *) malloc(hdr->a_syms);
  156.     read(fd, symb_table, hdr->a_syms);
  157.  
  158.     p = symb_table;
  159.     for (i = 0; i < nsyms; i++)
  160.     {
  161.         table_entry = (struct nlist *) p;
  162.         p += sizeof(struct nlist);
  163.         if (! ((table_entry->n_type & N_EXT) == 0
  164.             || (table_entry->n_type & N_TYPE) != N_TEXT))
  165.         {
  166.             if (entering)
  167.             {
  168.                 head = (DynamicFunctionList *)
  169.                        malloc(sizeof(DynamicFunctionList));
  170.                 scanner = head;
  171.                 entering = 0;
  172.             }
  173.             else
  174.             {
  175.                 scanner->next = (DynamicFunctionList *)
  176.                                 malloc(sizeof(DynamicFunctionList));
  177.                 scanner = scanner->next;
  178.             }
  179.             /*
  180.              * Add one for "_", ie
  181.              * overpaid() will be _overpaid
  182.              */
  183.  
  184.             q = strings + (table_entry->n_un.n_strx - 4) + 1;
  185.  
  186.             strcpy(scanner->funcname, q);
  187.             scanner->func = (func_ptr) (table_entry->n_value + entry_addr);
  188.             scanner->next = NULL;
  189.         }
  190.     }
  191.  
  192.     free(symb_table);
  193.     free(strings);
  194.     close(fd);
  195.     return(head);
  196. }
  197.  
  198. func_ptr
  199. dynamic_load(err)
  200.  
  201. char **err;
  202.  
  203. {
  204.     *err = "Dynamic load: Should not be here!";
  205.     return(NULL);
  206. }
  207.  
  208. /* 
  209.  *   ld -N -x -A SYMBOL_TABLE -T ADDR -o TEMPFILE FUNC -lc
  210.  */
  211.  
  212. execld(address, tmp_file, filename)
  213.  
  214. char *address, *tmp_file, *filename;
  215.  
  216. {
  217.     char command[256];
  218.     int retval;
  219.  
  220.     sprintf(command,"ld -N -x -A %s -T %lx -o %s  %s -lc -lm -ll",
  221.             pg_pathname,
  222.             address,
  223.             tmp_file,  filename);
  224.     retval = OurSystem(command);
  225.     return(retval);
  226. }
  227.